#include "InGameState.hpp"

#include "InMenuState.hpp"
#include "Game.hpp"
#include "LevelsProgressionBar.hpp"
#include "StatusBar.hpp"
#include "TowerPanel.hpp"
#include "InfosPanel.hpp"
#include "Board.hpp"

#include "ResourceManager.hpp"


InGameState::InGameState(Game* game, sf::RenderWindow* window)
    : ::GameState(game, window)
{
    loadTextures();
    loadSprites();

    levelsProgressionBar_ = new LevelsProgressionBar(window_);
    statusBar_ = new StatusBar(window_);
    towerPanel_ = new TowerPanel(window_);
    board_ = new Board(window_, towerPanel_);
    infosPanel_ = new InfosPanel(window_, board_, towerPanel_);
}

InGameState::~InGameState()
{
    delete levelsProgressionBar_;
    levelsProgressionBar_ = nullptr;

    delete statusBar_;
    statusBar_ = nullptr;

    delete towerPanel_;
    towerPanel_ = nullptr;

    delete infosPanel_;
    infosPanel_ = nullptr;

    delete board_;
    board_ = nullptr;

    ResourceManager<sf::Sprite>::instance()->remove("Pellet1");
    ResourceManager<sf::Sprite>::instance()->remove("Squirt1");
    ResourceManager<sf::Sprite>::instance()->remove("Dart1");
    ResourceManager<sf::Sprite>::instance()->remove("Frost1");
    ResourceManager<sf::Sprite>::instance()->remove("Swarm1");

    ResourceManager<sf::Sprite>::instance()->remove("Board_BG");
    ResourceManager<sf::Sprite>::instance()->remove("StatusBar_BG");
    ResourceManager<sf::Sprite>::instance()->remove("LevelsBar_BG");
    ResourceManager<sf::Sprite>::instance()->remove("TowerPanel_BG");
    ResourceManager<sf::Sprite>::instance()->remove("InfosPanel_BG");
}

void
InGameState::init()
{}

void
InGameState::reset()
{}

void
InGameState::handleEvents()
{
    sf::Event event;

    while (window_->pollEvent(event))
    {
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
            game_->changeState(InMenuState::instance(game_, window_));

        // if (board_->containMouseCursor(sf::Mouse::GetPosition()))
        //     ;
        // else if (towerPanel_->containMouseCursor(sf::Mouse::GetPosition()))
        //     ;
        // else if (infosPanel_->containMouseCursor(sf::Mouse::GetPosition()))
        //     ;
    }
}

void
InGameState::update()
{
    window_->clear(sf::Color(0, 0, 0));
}

void
InGameState::render()
{
    levelsProgressionBar_->render();
    statusBar_->render();
    towerPanel_->render();
    infosPanel_->render();
    board_->render();

    window_->display();
}

void
InGameState::loadSprites() const
{
    auto spriteManager = ResourceManager<sf::Sprite>::instance();
    auto towers = ResourceManager<sf::Texture>::instance()->get("Towers");
    auto statusBar_BG = ResourceManager<sf::Texture>::instance()->get("StatusBar_BG");
    auto board_BG = ResourceManager<sf::Texture>::instance()->get("Board_BG");
    auto levelsBar_BG = ResourceManager<sf::Texture>::instance()->get("LevelsBar_BG");
    auto towerPanel_BG = ResourceManager<sf::Texture>::instance()->get("TowerPanel_BG");
    auto infosPanel_BG = ResourceManager<sf::Texture>::instance()->get("InfosPanel_BG");

    spriteManager->add("Pellet1", new sf::Sprite(*towers, sf::IntRect(0, 0, 35, 35)));
    spriteManager->add("Dart1", new sf::Sprite(*towers, sf::IntRect(35, 0, 35, 35)));
    spriteManager->add("Squirt1", new sf::Sprite(*towers, sf::IntRect(70, 0, 35, 35)));
    spriteManager->add("Frost1", new sf::Sprite(*towers, sf::IntRect(105, 0, 35, 35)));
    spriteManager->add("Swarm1", new sf::Sprite(*towers, sf::IntRect(140, 0, 35, 35)));

    spriteManager->add("StatusBar_BG", new sf::Sprite(*statusBar_BG));
    spriteManager->add("Board_BG", new sf::Sprite(*board_BG));
    spriteManager->add("LevelsBar_BG", new sf::Sprite(*levelsBar_BG));
    spriteManager->add("TowerPanel_BG", new sf::Sprite(*towerPanel_BG));
    spriteManager->add("InfosPanel_BG", new sf::Sprite(*infosPanel_BG));
}

void
InGameState::loadTextures() const
{
    sf::Texture* towers = new sf::Texture;
    sf::Texture* board_bg = new sf::Texture;
    sf::Texture* statusBar_bg = new sf::Texture;
    sf::Texture* levelsBar_bg = new sf::Texture;
    sf::Texture* towerPanel_bg = new sf::Texture;
    sf::Texture* infosPanel_bg = new sf::Texture;

    loadTexture(towers, "resources/towers.png", "Towers");
    loadTexture(statusBar_bg, "resources/StatusBar_BG.png", "StatusBar_BG");
    loadTexture(levelsBar_bg, "resources/LevelsBar_BG.png", "LevelsBar_BG");
    loadTexture(towerPanel_bg, "resources/TowerPanel_BG.png", "TowerPanel_BG");
    loadTexture(board_bg, "resources/Board_BG.png", "Board_BG");
    loadTexture(infosPanel_bg, "resources/InfosPanel_BG.png", "InfosPanel_BG");
}

void
InGameState::loadTexture(sf::Texture* texture,
                         const std::string& fileName,
                         const std::string& textureName) const
{
    if (texture->loadFromFile(fileName))
        ResourceManager<sf::Texture>::instance()->add(textureName, texture);
    else
        throw Exception("Could not load texture: " + fileName);
}
